package jdos.gui;

import jdos.Dosbox;
import jdos.dos.Dos_programs;
import jdos.hardware.Keyboard;
import jdos.ints.Mouse;
import jdos.sdl.GUI;
import jdos.types.LogSeverities;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.MemoryImageSource;
import java.lang.reflect.Method;
///static public int LINK_START = ((1024 + 64) / 4); //Start right after the HMA
///static final private int EMM_PAGEFRAME4K = 0;//((0xE000*16)/4096);

public class MainFrame8088 implements GUI {
    //static public final int level = LogSeverities.LOG_NORMAL;
    static public final int level = LogSeverities.LOG_ERROR;
    
	public static int memsize = 1*1024*1024;
	
	public static int frameskip = 0;
	public static boolean scaleForced = false;
	
	public static void Init() {
		//Dos_programs.IMGMOUNT('0', 0,0,0,"D:\\system\\dos install1.img","floppy");
		
		//Dos_programs.IMGMOUNT('2', 16, 520, 63, "D:\\system\\dos44.img","hdd");
		Dos_programs.IMGMOUNT('2', 16, 520, 63, "D:\\system\\dosEGA.img","hdd");
		
		//Dos_programs.IMGMOUNT('2', 64, 1023, 63, "D:\\system\\dosEGA.img","hdd");

		//Dos_programs.BOOT('A');
		Dos_programs.BOOT('C');
		try{
			Thread.sleep(100000);
		}catch(Throwable t) {
		}
	}
	
	public static void main(final String[] args) {

		try {
			robot = new Robot();
		} catch (Throwable e) {
			System.out.println("Applet is not signed, mouse capture will not work");
		}

		DebugFrame.init();
		frame = new MyFrame();
		frame.setFocusTraversalKeysEnabled(false);
		frame.addFocusListener(new FocusListener() {
			private final KeyEventDispatcher altDisabler = new KeyEventDispatcher() {
				public boolean dispatchKeyEvent(KeyEvent e) {
					if (e.getKeyCode() == 18) {
						//Main.addEvent(e);
			        	Keyboard.KEYBOARD_AddKey(e);
						return true;
					}
					return false;
			       }
                };

                public void focusGained(FocusEvent e) {
                    KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(altDisabler);
                }

                public void focusLost(FocusEvent e) {
                    KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(altDisabler);
                }
            });

		panel = new JPanel() {
			public void paint(Graphics g) {
				if (Main.buffer2 != null) {
					g.drawImage(Main.buffer2, 0, 0, Main.buffer_width, Main.buffer_height, 0, 0, Main.buffer_width, Main.buffer_height, null);
				}
			}
		};
		
        panel.addMouseMotionListener((MyFrame)frame);
        panel.addMouseListener((MyFrame)frame);
        frame.addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                synchronized (Main.pauseMutex) {
                    Main.pauseMutex.notify();
                }
                try {mainThread.join(5000);} catch (Exception e1) {}
                if (!Dosbox.applet) {
                    System.exit(0);
                }
            }
        });
        Container contentPane = frame.getContentPane();
		contentPane.setLayout(new BorderLayout());
		frame.getContentPane().add(panel, BorderLayout.PAGE_START);

		Main.main(new MainFrame8088(), args);
		System.exit(0);

    }

    
    int[] pixels = new int[16 * 16];
    Image image = Toolkit.getDefaultToolkit().createImage(new MemoryImageSource(16, 16, pixels, 0, 16));
    Cursor transparentCursor = Toolkit.getDefaultToolkit().createCustomCursor(image, new Point(0, 0), "invisibleCursor");

    static Robot robot;
    static private boolean eatNextMouseMove = false;
    static private int last_x;
    static private int last_y;

    public void showProgress(String msg, int percent) {
        
    }

    static public void robotMouse(MouseEvent e, Point rel, int offX, int offY) {
        if (eatNextMouseMove) {
            last_x = e.getX()-offX;
            last_y = e.getY()-offY;
            eatNextMouseMove = false;
            return;
        }
        if (!Main.mouse_locked || robot == null)
            Main.addMouseEvent(new Main.MouseEvent1(e, offX, offY));
        else {
            int rel_x = e.getX() - last_x - offX;
            int rel_y = e.getY() - last_y - offY;
            float abs_x = (Mouse.mouse.x+rel_x* Main.mouse_sensitivity/100.0f)/(Mouse.mouse.max_x);
            float abs_y = (Mouse.mouse.y+rel_y* Main.mouse_sensitivity/100.0f)/(Mouse.mouse.max_y);
            Main.addMouseEvent(new Main.MouseEvent2(e, rel_x, rel_y, abs_x, abs_y, offX, offY));
            robotCenter(rel);
        }
    }
    static public void robotCenter(Point rel) {
        eatNextMouseMove = true;
        robot.mouseMove(rel.x+200, rel.y+200);
    }

    public void captureMouse(boolean on) {
        if (robot != null) {
            robotCenter(panel.getLocationOnScreen());
        }
    }
    public void showCursor(boolean on) {
        if (on)
            frame.setCursor(Cursor.getDefaultCursor());
        else
            frame.setCursor(transparentCursor);
    }
    public void setCursor(Cursor cursor) {
        if (cursor == null)
            cursor = transparentCursor;
        frame.setCursor(cursor);
    }

    public void setSize() {
    	int width = 640 + 20;
    	int height = 480 + 20;
        panel.setMinimumSize(new Dimension(width, height));
        panel.setMaximumSize(new Dimension(width, height));
        panel.setPreferredSize(new Dimension(width, height));
        frame.getContentPane().doLayout();
        frame.pack();
        if (!frame.isVisible())
            frame.setVisible(true);
    }
    public void dopaint() {
        panel.repaint();
    }
    public void setTitle(String title) {
        if (frame != null)
            frame.setTitle(title);
    }

    public static GraphicsConfiguration getDefaultConfiguration() {
        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice gd = ge.getDefaultScreenDevice();
        return gd.getDefaultConfiguration();
    }

    static BufferedImage tmpImage;

    private static Thread mainThread;
    private static JFrame frame;
    private static JPanel panel;

    private static class MyFrame extends JFrame implements KeyListener, WindowFocusListener, WindowListener, MouseListener, MouseMotionListener {
        public MyFrame() {
            addKeyListener(this);
            addWindowFocusListener(this);
            addWindowListener(this);
        }
        public void keyTyped(KeyEvent e) {

        }

        /** Handle the key pressed event from the text field. */
        public void keyPressed(KeyEvent e) {
        	Keyboard.KEYBOARD_AddKey(e);
            //Main.addKeyEvent(e);
        }

        /** Handle the key released event from the text field. */
        public void keyReleased(KeyEvent e) {
        	Keyboard.KEYBOARD_AddKey(e);
            //Main.addKeyEvent(e);
        }

        public void windowGainedFocus(WindowEvent e) {
            Main.addEvent(new Main.FocusChangeEvent(true));
            if (!Main.keyboardPaused) {
                synchronized (Main.pauseMutex) {
                    Main.pauseMutex.notify();
                }
            }
        }

        public void windowLostFocus(WindowEvent e) {
            Main.addEvent(new Main.FocusChangeEvent(false));
        }

        public void windowOpened(WindowEvent e) {
        }

        public void windowClosing(WindowEvent e) {
        }

        public void windowClosed(WindowEvent e) {
        }

        public void windowIconified(WindowEvent e) {
        }

        public void windowDeiconified(WindowEvent e) {
        }

        public void windowActivated(WindowEvent e) {
        }

        public void windowDeactivated(WindowEvent e) {
        }

        public void mousePressed(MouseEvent e) {
            Main.addMouseEvent(e);
        }

        public void mouseReleased(MouseEvent e) {
            Main.addMouseEvent(e);
        }

        public void mouseEntered(MouseEvent e) {
        }

        public void mouseExited(MouseEvent e) {
        }

        public void mouseClicked(MouseEvent e) {
            //if (e.getClickCount()==2 && e.getButton() == MouseEvent.BUTTON3) {
                //Main.GFX_CaptureMouse();
            //}
        }

        public void mouseMoved(MouseEvent e) {
            robotMouse(e, panel.getLocationOnScreen(), 0, 0);
        }

        public void mouseDragged(MouseEvent e) {
            robotMouse(e, panel.getLocationOnScreen(), 0, 0);
        }

    }
}
